package me.zhengjie.spider.manager;

import lombok.extern.slf4j.Slf4j;
import me.zhengjie.exception.SpiderRunningException;
import me.zhengjie.spider.common.SpiderAttributeBean;
import me.zhengjie.spider.common.SpiderConstant;
import me.zhengjie.spider.domain.video.VideoBean;
import me.zhengjie.spider.domain.video.VideoRuleBean;
import me.zhengjie.spider.rule.service.SpiderRuleService;
import me.zhengjie.spider.rule.service.dto.SpiderRuleDto;
import me.zhengjie.spider.rule.service.dto.SpiderRuleQueryCriteria;
import me.zhengjie.spider.util.pipeline.SpiderVideoGeneralVideoPipeline;
import me.zhengjie.spider.util.processor.SpiderVideoGeneralPageProcessor;
import me.zhengjie.spider.video.service.SpiderVideoService;
import me.zhengjie.spider.video.service.dto.SpiderVideoDto;
import me.zhengjie.spider.web.domain.SpiderWeb;
import me.zhengjie.utils.RedisUtils;
import me.zhengjie.utils.SpringContextHolder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Spider;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Component
public class SpiderVideoManager {

    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private SpiderAsyncManager spiderAsyncManager;
    @Autowired
    private SpiderVideoService spiderVideoService;
    @Autowired
    private SpiderRuleService spiderRuleService;

    public void doSpider(SpiderWeb spiderWeb, SpiderAttributeBean spiderAttributeBean) throws Exception {
        VideoRuleBean videoRuleBean = buildSpiderVideoRuleBean(spiderWeb);
        SpiderVideoGeneralPageProcessor spiderVideoGeneralPageProcessor = SpringContextHolder.getBean(SpiderVideoGeneralPageProcessor.class);
        SpiderVideoGeneralVideoPipeline spiderVideoGeneralVideoPipeline = SpringContextHolder.getBean(SpiderVideoGeneralVideoPipeline.class);
        spiderVideoGeneralPageProcessor.setRuleBean(videoRuleBean);
        spiderVideoGeneralVideoPipeline.setRuleBean(videoRuleBean);

        Spider.create(spiderVideoGeneralPageProcessor).addUrl(videoRuleBean.getMainLink()).addPipeline(spiderVideoGeneralVideoPipeline).thread(spiderAttributeBean.getThread()).run();
    }

    public void afterDoSpider(SpiderWeb spiderWeb, SpiderAttributeBean spiderAttributeBean) {
        VideoRuleBean videoRuleBean = buildSpiderVideoRuleBean(spiderWeb);
        List<SpiderVideoDto> spiderVideoVOList = spiderVideoService.findUnSpiderByWebIdAnd(spiderWeb.getWebId());
        for (SpiderVideoDto spiderVideoDto : spiderVideoVOList) {
            // consume
            try {
                VideoBean videoBean = new VideoBean();
                BeanUtils.copyProperties(spiderVideoDto, videoBean);
                spiderAsyncManager.afterMath(videoBean, videoRuleBean, spiderAttributeBean);
            } catch (Exception e) {
                throw new SpiderRunningException("爬取明细失败： " + e);
            }
        }
    }

    public void resetRedisCache(Long webId) {
        String redisKey = String.format(SpiderConstant.SPIDER_VIDEO_KEY, webId.toString());
        log.info("redisKey:{}", redisKey);
        this.redisUtils.del(redisKey);
        List<String> spiderVideoVOList = spiderVideoService.queryAllByWebId(webId);
        log.info("ID为{}的数据大小{}", webId, spiderVideoVOList.size());
        spiderVideoVOList.forEach(href -> {
            String item = webId + SpiderConstant.COLON + href;
            if (!this.redisUtils.hHasKey(redisKey, item)) {
                this.redisUtils.hset(redisKey, item, null);
            }
        });
    }

    public VideoRuleBean buildSpiderVideoRuleBean(SpiderWeb spiderWeb) {
        SpiderRuleQueryCriteria searchCriteria = new SpiderRuleQueryCriteria();
        searchCriteria.setWebId(spiderWeb.getWebId());
        List<SpiderRuleDto> spiderRuleVOList = spiderRuleService.queryAll(searchCriteria);
        Map<String, String> map = spiderRuleVOList.stream().collect(Collectors.toMap(SpiderRuleDto::getFieldCode, SpiderRuleDto::getRule));
        VideoRuleBean videoRuleBean = new VideoRuleBean();
        videoRuleBean.setAlt(this.getValueByMap(map, SpiderConstant.ALT));
        videoRuleBean.setImg(this.getValueByMap(map, SpiderConstant.IMG));
        videoRuleBean.setHref(this.getValueByMap(map, SpiderConstant.HREF));
        videoRuleBean.setTargetLink(this.getValueByMap(map, SpiderConstant.TARGET_LINK));
        videoRuleBean.setType(this.getValueByMap(map, SpiderConstant.TYPE));
        videoRuleBean.setTag(this.getValueByMap(map, SpiderConstant.TAG));
        videoRuleBean.setPlayLink(this.getValueByMap(map, SpiderConstant.PLAY_LINK));
        videoRuleBean.setTargetType(this.getValueByMap(map, SpiderConstant.TARGET_TYPE));
        videoRuleBean.setPlayLinkDomain(this.getValueByMap(map, SpiderConstant.PLAY_LINK_DOMAIN));
        videoRuleBean.setMainLink(spiderWeb.getWebAddress());
        videoRuleBean.setWebId(spiderWeb.getWebId());
        videoRuleBean.setDomain(spiderWeb.getDomain());
        return videoRuleBean;
    }

    public String getValueByMap(Map<String, String> map, String key) {
        if (map.containsKey(key)) {
            return map.get(key);
        }
        return null;
    }
}
